﻿using System.Buffers;
using Microsoft.Extensions.ObjectPool;

namespace ConsoleApp;

// ArrayPool: 共享的数组池，减少频繁创建/销毁大数组的开销。
// MemoryPool: 用于管理 Memory<T> 或 Span<T> 的底层内存。
// ObjectPool: 对象池模式是一种创建和管理一组可复用对象的设计模式
// Install-Package Microsoft.Extensions.ObjectPool
public class DemoPool
{
    public void ArrayPoolTest()
    {
        var pool = ArrayPool<byte>.Shared;
        var buffer = pool.Rent(1024); // 租用
        try {
            // 使用 buffer...
        }
        finally {
            pool.Return(buffer); // 归还
        }
    }

    public void MemoryPoolTest()
    {
        var pool = MemoryPool<byte>.Shared;
        var memoryOwner = pool.Rent(1024);
        var memory = memoryOwner.Memory;
        try {
            // 使用 memory...
        }
        finally {
            memoryOwner.Dispose(); // 归还
        }
    }

    // 定义策略
    public class BufferPolicy : PooledObjectPolicy<byte[]>
    {
        public override byte[] Create() => new byte[1024];
        public override bool Return(byte[] obj) => true; // 简单示例，实际可重置对象
    }
    
    public void ObjectPoolTest()
    {
        // 使用池
        var pool = new DefaultObjectPool<byte[]>(new BufferPolicy());
        var buffer = pool.Get();
        try {
            // 使用 buffer...
        }
        finally {
            pool.Return(buffer);
        }
    }
    
    static void Main(string[] args)
    {
        var pool = new DefaultObjectPool<DatabaseConnection>(new DefaultPooledObjectPolicy<DatabaseConnection>(), 20);
        PerformDatabaseOperations(pool);
    }

    private static void PerformDatabaseOperations(ObjectPool<DatabaseConnection> pool)
    {
        var connection = pool.Get();
        try
        {
            // 使用连接
            connection.Open();
            // 模拟数据库操作
            Console.WriteLine("Doing some database operations");
            connection.Close();
        }
        finally
        {
            // 释放连接回池中
            pool.Return(connection);
        }
    }

    private static async ValueTask PerformDatabaseOperationsAsync(ObjectPool<DatabaseConnection> pool)
    {
        var connection = pool.Get();
        try
        {
            // 异步使用连接
            await connection.OpenAsync();
            // 模拟数据库操作
            Console.WriteLine("Doing some database operations asynchronously");
        }
        finally
        {
            // 释放连接回池中
            pool.Return(connection);
        }
    }
}

// class ObjectPool<T> where T : new()
// {
//     private readonly Stack<T> pool = new Stack<T>();
//
//     public T GetObject()
//     {
//         return pool.Count > 0 ? pool.Pop() : new T();
//     }
//
//     public void ReturnObject(T obj)
//     {
//         pool.Push(obj);
//     }
// }

// // 使用示例
// ObjectPool<Student> studentPool = new ObjectPool<Student>();
// for (int i = 0; i < 1000000; i++)
// {
//     Student student = studentPool.GetObject();
//     student.StudentId = i;
//     student.Name = $"Student{i}";
//     // 处理学生对象...
//     studentPool.ReturnObject(student);
// }

public class DatabaseConnection
{
    public ValueTask OpenAsync()
    {
        Console.WriteLine("Connection Opened Asynchronously");
        return new ValueTask(); // 假设打开连接是即时完成的
    }

    public void Open() => Console.WriteLine("Connection Opened");
    public void Close() => Console.WriteLine("Connection Closed");
}